<template>
  <div ref="containerDom" class="tags-view" v-if="!showTags">
    <span v-show="isShowArrow" class="arrow-left">
      <IconifyIconOffline :icon="ArrowLeftSLine" @click="handleScroll(200)" />
    </span>
    <div ref="scrollbarDom" class="scroll-container">
      <div
        class="select-none tab"
        ref="tabDom"
        :style="{ transform: `translateX(${translateX}px)` }"
      >
        <div
          :ref="'dynamic' + index"
          v-for="(item, index) in multiTags"
          :key="index"
          :class="[
            'scroll-item is-closable',
            isActive(item, 'is-active'),
            route?.path === item.router && showModel === 'card'
              ? 'card-active'
              : ''
          ]"
          @contextmenu.prevent="openMenu(item, $event)"
          @mouseenter.prevent="onMouse(index, true)"
          @mouseleave.prevent="onMouse(index, false)"
          @click="tagOnClick(item)"
        >
          <router-link
            :to="item.router"
            class="dark:!text-text_color_primary dark:hover:!text-primary"
          >
            {{ item.text }}
          </router-link>
          <span
            v-if="iconIsActive(item, index)"
            class="el-icon-close"
            @click.stop="deleteTag(item, 1)"
          >
            <IconifyIconOffline :icon="CloseBold" />
          </span>
          <div
            :ref="'schedule' + index"
            v-if="showModel !== 'card'"
            :class="[isActive(item, 'schedule-active')]"
          />
        </div>
      </div>
    </div>
    <span v-show="isShowArrow" class="arrow-right">
      <IconifyIconOffline :icon="ArrowRightSLine" @click="handleScroll(-200)" />
    </span>
    <!-- 右键菜单按钮 -->
    <transition name="el-zoom-in-top">
      <ul
        v-show="visible"
        :key="Math.random()"
        :style="{ left: buttonLeft + 'px', top: buttonTop + 'px' }"
        class="contextmenu"
      >
        <div
          v-for="(item, key) in tagsViews.slice(0, 6)"
          :key="key"
          style="display: flex; align-items: center"
        >
          <li v-if="item.show" @click="selectTag(key)">
            <IconifyIconOffline :icon="item.icon" />
            {{ item.text }}
          </li>
        </div>
      </ul>
    </transition>
    <!-- 右侧功能按钮 -->
    <el-dropdown
      trigger="click"
      placement="bottom-end"
      @mouseenter.prevent="moveIndex = -1"
      @command="handleCommand"
    >
      <span class="arrow-down">
        <IconifyIconOffline :icon="ArrowDown" class="dark:text-white" />
      </span>
      <template #dropdown>
        <el-dropdown-menu>
          <el-dropdown-item
            v-for="(item, key) in tagsViews"
            :key="key"
            :command="{ key, item }"
            :divided="item.divided"
            :disabled="item.disabled"
          >
            <IconifyIconOffline :icon="item.icon" />
            {{ item.text }}
          </el-dropdown-item>
        </el-dropdown-menu>
      </template>
    </el-dropdown>
  </div>
</template>

<script setup lang="ts">
import { useResizeObserver, useFullscreen } from "@vueuse/core";
import {
  ref,
  unref,
  nextTick,
  computed,
  getCurrentInstance,
  onMounted
} from "vue";

import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
import ArrowDown from "@iconify-icons/ri/arrow-down-s-line";
import ArrowRightSLine from "@iconify-icons/ri/arrow-right-s-line";
import ArrowLeftSLine from "@iconify-icons/ri/arrow-left-s-line";
import CloseBold from "@iconify-icons/ep/close-bold";
import { useRoute, useRouter } from "vue-router";
import { useAppHooks } from "@/core/pinia/store/app.store";
import { useMenuHooks } from "@/core/pinia/store/menu.store";
import { Tags } from "@/core/pinia/interface";
import { getTagsViews } from "./provider";
import { useSettingHooks } from "@/core/pinia/store/setting.store";
const app = useAppHooks();
const setting = useSettingHooks();
const menuHooks = useMenuHooks();
const instance = getCurrentInstance();
const route = useRoute();
const router = useRouter();
const visible = ref(false);
const isShowArrow = ref(false);
const scrollbarDom = ref();
const tabDom = ref();
const containerDom = ref();
const { isFullscreen, toggle } = useFullscreen();
const buttonTop = ref(0);
const buttonLeft = ref(0);
const activeIndex = ref(0);
const moveIndex = ref(0);
/** 转变 */
const translateX = ref(0);
/** 是否显示tags */
const showTags = computed(() => {
  return app.getPages.hideTabs;
});
const tagsViews = computed(() => {
  const select = route.path === menuHooks.getDefaultActive.link;
  const isActive = menuHooks.cacheTags?.[moveIndex.value]?.active;
  const tags = getTagsViews(
    menuHooks.cacheTags.length,
    moveIndex.value,
    isActive && select
  );
  if (moveIndex.value === -1) {
    if (!app.getHiddenTabs) {
      tags[1].icon = Fullscreen;
      tags[1].text = "内容全屏";
    } else {
      tags[1].icon = ExitFullscreen;
      tags[1].text = "退出全屏";
    }
    if (isFullscreen.value) {
      tags[2].icon = ExitFullscreen;
      tags[2].text = "整体退出全屏";
    } else {
      tags[2].icon = Fullscreen;
      tags[2].text = "整体页面全屏";
    }
  }
  return tags;
});
/** tags 显示模式 */
const showModel = computed(() => {
  return app.getPages.showModel;
});
/** 获取已经存在的tags */
const multiTags = computed(() => {
  return menuHooks.getCacheTags;
});
// 当前右键选中的路由信息
const currentSelect = ref<Tags>({} as Tags);
const iconIsActive = computed(() => {
  return (item: Tags, index: number) => {
    if (index === 0) return false;
    return item.active || index === activeIndex.value;
  };
});

const isActive = computed(() => {
  return (item: Tags, key: string) => {
    return item.active ? key : "";
  };
});

const toggleClass = (flag: boolean, clsName: string, target?: HTMLElement) => {
  const targetEl = target || document.body;
  let { className } = targetEl;
  className = className.replace(clsName, "").trim();
  targetEl.className = flag ? `${className} ${clsName} ` : className;
};
/** 鼠标移入添加激活样式 */
const onMouse = (index: number, enter: boolean) => {
  if (enter) {
    moveIndex.value = index;
    visible.value = false;
  }
  activeIndex.value = enter ? index : -1;
  if (unref(showModel) === "smart") {
    const element = instance?.refs["schedule" + index]?.[0] as HTMLElement;
    const isActive = element?.classList.contains("schedule-active");
    if (element && !isActive) {
      toggleClass(enter, "schedule-in", element);
      toggleClass(!enter, "schedule-out", element);
    }
  } else {
    const element = instance?.refs["dynamic" + index]?.[0] as HTMLElement;
    const isActive = element?.classList.contains("card-active");
    if (element && !isActive) {
      toggleClass(enter, "card-in", element);
      toggleClass(!enter, "card-out", element);
    }
  }
};

/** 触发tags标签切换 */
const tagOnClick = (item: Tags) => {
  menuHooks.changeCacheTags(item);
  console.log(item);
  if (item.moda !== "LINK") {
    router.push({
      path: item.router
    });
  } else {
    window.open(item.link, "_blank");
  }
};

/** 删除tags */
const deleteTag = (item: Tags, sign?: number) => {
  const reset = menuHooks.delCacheTags(item.id, sign || 0);
  setting.handleAliveRoute(route);
  //TODO 删除后是否需要路由跳转
  if (reset) {
    router.push({
      path: menuHooks.getDefaultActive.router
    });
  }
};

const openMenu = (tag: Tags, e: MouseEvent) => {
  visible.value = false;
  currentSelect.value = tag;
  const menuMinWidth = 105;
  const offsetLeft = unref(containerDom).getBoundingClientRect().left;
  const offsetWidth = unref(containerDom).offsetWidth;
  const maxLeft = offsetWidth - menuMinWidth;
  const left = e.clientX - offsetLeft + 5;
  if (left > maxLeft) {
    buttonLeft.value = maxLeft;
  } else {
    buttonLeft.value = left;
  }
  buttonTop.value = e.clientY - 40;
  nextTick(() => {
    visible.value = true;
  });
};

const handleScroll = (offset: number): void => {
  const width = scrollbarDom.value ? scrollbarDom.value?.offsetWidth : 0;
  const tabWidth = tabDom.value ? tabDom.value.offsetWidth : 0;
  if (offset > 0) {
    translateX.value = Math.min(0, translateX.value + offset);
  } else {
    if (width < tabWidth) {
      if (translateX.value >= -(tabWidth - width)) {
        translateX.value = Math.max(
          translateX.value + offset,
          width - tabWidth
        );
      }
    } else {
      translateX.value = 0;
    }
  }
};

/** 触发右键中菜单的点击事件 */
const selectTag = (key: number) => {
  switch (key) {
    case 0:
      onFresh();
      break;
    default:
      deleteTag(currentSelect.value, key);
  }
};

const handleCommand = (command: { key: number }) => {
  const { key } = command;
  switch (key) {
    case 0:
      onFresh();
      break;
    case 1:
      if (app.getHiddenTabs) {
        tagsViews.value[1].icon = Fullscreen;
        tagsViews.value[1].text = "内容全屏";
      } else {
        tagsViews.value[1].icon = ExitFullscreen;
        tagsViews.value[1].text = "退出全屏";
      }
      app.setHiddenTabs(!app.getHiddenTabs);
      break;
    case 2:
      if (!isFullscreen.value) {
        tagsViews.value[2].icon = ExitFullscreen;
        tagsViews.value[2].text = "整体退出全屏";
      } else {
        tagsViews.value[2].icon = Fullscreen;
        tagsViews.value[2].text = "整体页面全屏";
      }
      toggle();
      break;
  }
};
/**  -------------------------------------------------分界线-------------------------------------------- */
const moveToView = async (): Promise<void> => {
  await nextTick();
  const index = multiTags.value.findIndex(item => {
    return route?.path === item.router;
  });
  const tabNavPadding = 10;
  if (!instance?.refs["dynamic" + index]) return;
  const tabItemEl = instance?.refs["dynamic" + index]?.[0] as HTMLElement;
  const tabItemElOffsetLeft = tabItemEl?.offsetLeft;
  const tabItemOffsetWidth = tabItemEl?.offsetWidth;
  // 标签页导航栏可视长度（不包含溢出部分）
  const scrollbarDomWidth = scrollbarDom.value
    ? scrollbarDom.value?.offsetWidth
    : 0;

  // 已有标签页总长度（包含溢出部分）
  const tabDomWidth = tabDom.value ? tabDom.value?.offsetWidth : 0;

  scrollbarDomWidth <= tabDomWidth
    ? (isShowArrow.value = true)
    : (isShowArrow.value = false);
  if (tabDomWidth < scrollbarDomWidth || tabItemElOffsetLeft === 0) {
    translateX.value = 0;
  } else if (tabItemElOffsetLeft < -translateX.value) {
    // 标签在可视区域左侧
    translateX.value = -tabItemElOffsetLeft + tabNavPadding;
  } else if (
    tabItemElOffsetLeft > -translateX.value &&
    tabItemElOffsetLeft + tabItemOffsetWidth <
      -translateX.value + scrollbarDomWidth
  ) {
    // 标签在可视区域
    translateX.value = Math.min(
      0,
      scrollbarDomWidth -
        tabItemOffsetWidth -
        tabItemElOffsetLeft -
        tabNavPadding
    );
  } else {
    // 标签在可视区域右侧
    translateX.value = -(
      tabItemElOffsetLeft -
      (scrollbarDomWidth - tabNavPadding - tabItemOffsetWidth)
    );
  }
};

/** 刷新路由 */
const onFresh = () => {
  const { fullPath, query } = unref(route);
  router.replace({
    path: "/redirect" + fullPath,
    query
  });
  visible.value = false;
  setting.handleAliveRoute(route, "refresh");
};

const addDocumentListoner = () => {
  document.addEventListener("click", () => (visible.value = false));
};

onMounted(() => {
  if (!instance) return;
  addDocumentListoner();
  useResizeObserver(scrollbarDom, () => moveToView());
});
</script>

<style lang="scss" scoped>
@import url("./index.scss");
</style>
